package com.sky.employee.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.sky.constant.MessageConstant;
import com.sky.constant.PasswordConstant;
import com.sky.constant.StatusConstant;
import com.sky.context.AlibabaTTL;
import com.sky.dto.EmployeeDTO;
import com.sky.dto.EmployeeLoginDTO;
import com.sky.dto.EmployeePageQueryDTO;
import com.sky.dto.PasswordEditDTO;
import com.sky.employee.mapper.EmployeeMapper;
import com.sky.employee.service.EmployeeService;
import com.sky.entity.Employee;
import com.sky.exception.AccountLockedException;
import com.sky.exception.AccountNotFoundException;
import com.sky.exception.PasswordErrorException;
import com.sky.result.PageResult;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * 员工管理 serviceImpl
 */
@Slf4j
@Service
public class EmployeeServiceImpl implements EmployeeService {

    @Resource
    private EmployeeMapper employeeMapper;




    /**
     * 后台  员工登录
     * @param employeeLoginDTO
     */
    @Override
    public Employee login(EmployeeLoginDTO employeeLoginDTO) {
        //取值
        String username = employeeLoginDTO.getUsername();
        String password = employeeLoginDTO.getPassword();

        //查询
        Employee employee = employeeMapper.selectEmpByUsername(username);

        //非空判断
        if(Objects.isNull(employee)){
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        //密码比较
        // TODO 后期需要进行MD5加密 在进行密码比较  -- 已完成
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        if( !employee.getPassword().equals(password) ){
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }

        //账户锁定状态
        if(employee.getStatus() == StatusConstant.DISABLE){
            throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
        }

        //返回
        return employee;
    }



    /**
     * 后台  新增员工
     *      TODO 需要修改为创建、修改用户ID  -- Aop完成
     * @param employeeDTO
     */
    @Override
    public void saveEmployee(EmployeeDTO employeeDTO) {
        //属性拷贝 并创建数据库映射实体类
        Employee employee = JSON.parseObject(JSON.toJSONString(employeeDTO, SerializerFeature.WriteMapNullValue), Employee.class);
        //空字段赋值
        employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes())).setStatus(StatusConstant.ENABLE);
                //Aop解决
                //.setCreateTime(LocalDateTime.now())
                //.setUpdateTime(LocalDateTime.now())
                //.setCreateUser(Long.valueOf(AlibabaTTL.threadLocalGet().toString()))
                //.setUpdateUser(Long.valueOf(AlibabaTTL.threadLocalGet().toString()));
        //新增
        Integer count = employeeMapper.insertEmployee(employee);
        log.info("新增数据影响行数：{}", count);
    }



    /**
     * 后台 员工分页条件查询
     * @param employeePageQueryDTO
     */
    @Override
    public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {
        // 1.PageHelper设置分页参数 ， 排序参数
        PageHelper.startPage(employeePageQueryDTO.getPage(), employeePageQueryDTO.getPageSize(), "create_time desc");

        // 2.查询返回的集合 封装为PageHelper的数据集合
        Page<Employee> page = employeeMapper.page(employeePageQueryDTO);

        // 3.封装返回数据
        return new PageResult(page.getTotal(), page.getResult());
    }



    /**
     * 后台 员工启用、禁用
     * @param id
     * @param status
     */
    @Override
    public void startOrStop(Long id, Integer status) {
        // 1.封装数据到实体
        Employee employee = Employee.builder()
                .id(id)
                .status(status)
                //Aop解决
                //.updateTime(LocalDateTime.now())
                //.updateUser(Long.valueOf(AlibabaTTL.threadLocalGet().toString()))
                .build();
        // 2.调方法
        Integer count = employeeMapper.updateById(employee);
        log.info("id:{} ,修改员工数据，影响行数：{}", id, count);
    }



    /**
     * 后台 根据id查询
     * @param id
     */
    @Override
    public Employee getById(Long id) {
        return employeeMapper.selectById(id).setPassword("******");
    }



    /**
     * 后台 根据id修改
     * @param employeeDTO
     */
    @Override
    public void updateById(EmployeeDTO employeeDTO) {
        //对象拷贝
        Employee employee = JSON.parseObject(JSON.toJSONString(employeeDTO, SerializerFeature.WriteMapNullValue), Employee.class);
        //Aop解决
        //employee.setUpdateUser(Long.valueOf(AlibabaTTL.threadLocalGet().toString())).setUpdateTime(LocalDateTime.now());
        //调方法
        Integer count = employeeMapper.updateById(employee);
        log.info("id:{} ,编辑员工信息,影响行数：==> {}", employeeDTO.getId(), count);
    }



    /**
     * 员工管理
     *         修改密码
     */
    @Override
    public void updatePasswordById(PasswordEditDTO passwordEditDTO) {
        // 1.先查询员工数据 非空判断
        Employee employee = employeeMapper.selectById(passwordEditDTO.getEmpId());
        if(null == employee){
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        // 2.比较旧密码与前端传递旧密码值是否一致
        if( !employee.getPassword().equals(passwordEditDTO.getOldPassword()) ){
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }

        // 3.加密处理
        String newPassword = DigestUtils.md5DigestAsHex(passwordEditDTO.getNewPassword().getBytes());

        // 4.封装数据
        Employee emp = Employee.builder().id(passwordEditDTO.getEmpId()).password(newPassword).build();

        // 5.修改
        Integer count = employeeMapper.updateById(emp);
        log.info("id: {},修改密码成功，影响行数: ==> {}", passwordEditDTO.getEmpId(), count);
    }


}
